home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2002 #11 / Amiga Plus CD - 2002 - No. 11.iso / Tools / Development / ncurses-5.3 / ncurses / tinfo / comp_expand.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-10-27  |  6.2 KB  |  185 lines

  1. /****************************************************************************
  2.  * Copyright (c) 1998,2000,2001 Free Software Foundation, Inc.              *
  3.  *                                                                          *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a  *
  5.  * copy of this software and associated documentation files (the            *
  6.  * "Software"), to deal in the Software without restriction, including      *
  7.  * without limitation the rights to use, copy, modify, merge, publish,      *
  8.  * distribute, distribute with modifications, sublicense, and/or sell       *
  9.  * copies of the Software, and to permit persons to whom the Software is    *
  10.  * furnished to do so, subject to the following conditions:                 *
  11.  *                                                                          *
  12.  * The above copyright notice and this permission notice shall be included  *
  13.  * in all copies or substantial portions of the Software.                   *
  14.  *                                                                          *
  15.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
  16.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
  17.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
  18.  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
  19.  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
  20.  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
  21.  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
  22.  *                                                                          *
  23.  * Except as contained in this notice, the name(s) of the above copyright   *
  24.  * holders shall not be used in advertising or otherwise to promote the     *
  25.  * sale, use or other dealings in this Software without prior written       *
  26.  * authorization.                                                           *
  27.  ****************************************************************************/
  28.  
  29. /****************************************************************************
  30.  *  Author: Thomas E. Dickey <dickey@clark.net> 1998                        *
  31.  ****************************************************************************/
  32.  
  33. #include <curses.priv.h>
  34.  
  35. #include <ctype.h>
  36. #include <tic.h>
  37.  
  38. MODULE_ID("$Id: comp_expand.c,v 1.17 2001/09/22 19:16:52 tom Exp $")
  39.  
  40. static int
  41. trailing_spaces(const char *src)
  42. {
  43.     while (*src == ' ')
  44.     src++;
  45.     return *src == 0;
  46. }
  47.  
  48. /* this deals with differences over whether 0x7f and 0x80..0x9f are controls */
  49. #define REALCTL(s) (UChar(*(s)) < 127 && iscntrl(UChar(*(s))))
  50. #define REALPRINT(s) (UChar(*(s)) < 127 && isprint(UChar(*(s))))
  51.  
  52. NCURSES_EXPORT(char *)
  53. _nc_tic_expand
  54. (const char *srcp, bool tic_format, int numbers)
  55. {
  56.     static char *buffer;
  57.     static size_t length;
  58.  
  59.     int bufp;
  60.     const char *str = VALID_STRING(srcp) ? srcp : "";
  61.     bool islong = (strlen(str) > 3);
  62.     size_t need = (2 + strlen(str)) * 4;
  63.     int ch;
  64.  
  65.     if (buffer == 0 || need > length) {
  66.     if ((buffer = typeRealloc(char, length = need, buffer)) == 0)
  67.           return 0;
  68.     }
  69.  
  70.     bufp = 0;
  71.     while ((ch = UChar(*str)) != 0) {
  72.     if (ch == '%' && REALPRINT(str + 1)) {
  73.         buffer[bufp++] = *str++;
  74.         /*
  75.          * Though the character literals are more compact, most
  76.          * terminal descriptions use numbers and are not easy
  77.          * to read in character-literal form.
  78.          */
  79.         switch (numbers) {
  80.         case -1:
  81.         if (str[0] == S_QUOTE
  82.             && str[1] != '\\'
  83.             && REALPRINT(str + 1)
  84.             && str[2] == S_QUOTE) {
  85.             sprintf(buffer + bufp, "{%d}", str[1]);
  86.             bufp += strlen(buffer + bufp);
  87.             str += 2;
  88.         } else {
  89.             buffer[bufp++] = *str;
  90.         }
  91.         break;
  92.         /*
  93.          * If we have a "%{number}", try to translate it into
  94.          * a "%'char'" form, since that will run a little faster
  95.          * when we're interpreting it.  Also, having one form
  96.          * for the constant makes it simpler to compare terminal
  97.          * descriptions.
  98.          */
  99.         case 1:
  100.         if (str[0] == L_BRACE
  101.             && isdigit(UChar(str[1]))) {
  102.             char *dst = 0;
  103.             long value = strtol(str + 1, &dst, 0);
  104.             if (dst != 0
  105.             && *dst == R_BRACE
  106.             && value < 127
  107.             && value != '\\'    /* FIXME */
  108.             && isprint((int) value)) {
  109.             ch = (int) value;
  110.             buffer[bufp++] = S_QUOTE;
  111.             if (ch == '\\'
  112.                 || ch == S_QUOTE)
  113.                 buffer[bufp++] = '\\';
  114.             buffer[bufp++] = ch;
  115.             buffer[bufp++] = S_QUOTE;
  116.             str = dst;
  117.             } else {
  118.             buffer[bufp++] = *str;
  119.             }
  120.         } else {
  121.             buffer[bufp++] = *str;
  122.         }
  123.         break;
  124.         default:
  125.         buffer[bufp++] = *str;
  126.         break;
  127.         }
  128.     } else if (ch == 128) {
  129.         buffer[bufp++] = '\\';
  130.         buffer[bufp++] = '0';
  131.     } else if (ch == '\033') {
  132.         buffer[bufp++] = '\\';
  133.         buffer[bufp++] = 'E';
  134.     } else if (ch == '\\' && tic_format && (str == srcp || str[-1] != '^')) {
  135.         buffer[bufp++] = '\\';
  136.         buffer[bufp++] = '\\';
  137.     } else if (ch == ' ' && tic_format && (str == srcp ||
  138.                            trailing_spaces(str))) {
  139.         buffer[bufp++] = '\\';
  140.         buffer[bufp++] = 's';
  141.     } else if ((ch == ',' || ch == ':' || ch == '^') && tic_format) {
  142.         buffer[bufp++] = '\\';
  143.         buffer[bufp++] = ch;
  144.     } else if (REALPRINT(str)
  145.            && (ch != ','
  146.                && ch != ':'
  147.                && !(ch == '!' && !tic_format)
  148.                && ch != '^'))
  149.         buffer[bufp++] = ch;
  150. #if 0                /* FIXME: this would be more readable (in fact the whole 'islong' logic should be removed) */
  151.     else if (ch == '\b') {
  152.         buffer[bufp++] = '\\';
  153.         buffer[bufp++] = 'b';
  154.     } else if (ch == '\f') {
  155.         buffer[bufp++] = '\\';
  156.         buffer[bufp++] = 'f';
  157.     } else if (ch == '\t' && islong) {
  158.         buffer[bufp++] = '\\';
  159.         buffer[bufp++] = 't';
  160.     }
  161. #endif
  162.     else if (ch == '\r' && (islong || (strlen(srcp) > 2 && str[1] == '\0'))) {
  163.         buffer[bufp++] = '\\';
  164.         buffer[bufp++] = 'r';
  165.     } else if (ch == '\n' && islong) {
  166.         buffer[bufp++] = '\\';
  167.         buffer[bufp++] = 'n';
  168.     }
  169. #define UnCtl(c) ((c) + '@')
  170.     else if (REALCTL(str) && ch != '\\'
  171.          && (!islong || isdigit(UChar(str[1])))) {
  172.         (void) sprintf(&buffer[bufp], "^%c", UnCtl(ch));
  173.         bufp += 2;
  174.     } else {
  175.         (void) sprintf(&buffer[bufp], "\\%03o", ch);
  176.         bufp += 4;
  177.     }
  178.  
  179.     str++;
  180.     }
  181.  
  182.     buffer[bufp] = '\0';
  183.     return (buffer);
  184. }
  185.